package com.example.aigc_education.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.domain.Note;
import com.example.aigc_education.domain.NoteTag;
import com.example.aigc_education.domain.dto.NoteDTO;
import com.example.aigc_education.domain.vo.NoteTagVO;
import com.example.aigc_education.domain.vo.NoteVO;
import com.example.aigc_education.mapper.NoteMapper;
import com.example.aigc_education.mapper.NoteTagMapper;
import com.example.aigc_education.service.NoteService;
import com.example.aigc_education.service.NoteTagService;
import com.example.aigc_education.service.converter.NoteConverter;
import com.example.aigc_education.utils.SecurityUtils;
import com.example.aigc_education.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 23918
* @description 针对表【stu_note】的数据库操作Service实现
* @createDate 2024-11-04 19:29:51
*/
@Service
public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note>
    implements NoteService{

    @Resource
    private NoteConverter noteConverter;

    @Resource
    private NoteTagService noteTagService;

    @Resource
    private NoteMapper noteMapper;

    @Resource
    private NoteTagMapper noteTagMapper;

    /**
     * 搜索该计划下的所有的笔记
     *
     * @param themeId 该计划id
     * @return 所有的笔记集合
     */
    @Override
    public List<NoteVO> noteList(Long themeId){
        try{
            Long userId = SecurityUtils.getUserId();

            LambdaQueryWrapper<Note> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Note::getCreateBy, userId);
            queryWrapper.eq(Note::getThemeId, themeId);
            // 状态是1，表示没删除
            queryWrapper.eq(Note::getStatus, 1);
            // 根据修改时间降序排序
            queryWrapper.orderByDesc(Note::getUpdateTime);

            List<Note> noteList = this.list(queryWrapper);
            return noteListTONoteVOList(noteList);

        }catch (Exception e){
            throw new BusinessException("搜索所有笔记失败");
        }
    }

    /**
     * 根据笔记的标模糊查询笔记
     *
     * @param noteId 笔记的id
     * @return 笔记的集合，并且根据创建时间机降序排序
     */
    @Override
    public List<NoteVO> queryByNoteId(Long noteId){
        try {
            Long userId = SecurityUtils.getUserId();

            LambdaQueryWrapper<Note> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Note::getCreateBy, userId);
            queryWrapper.like(Note::getNoteId, noteId);
            // 状态是1，表示没删除
            queryWrapper.eq(Note::getStatus, 1);
            // 根据修改的时间降序排序
            queryWrapper.orderByDesc(Note::getUpdateTime);

            List<Note> noteList = this.list(queryWrapper);

            return noteListTONoteVOList(noteList);
        }catch (Exception e){
            throw new BusinessException("模糊搜索笔记失败");
        }
    }

    /**
     * 软删除笔记。只是笔记的状态改为0，表示该笔记是已经被删除的
     * @param noteId    笔记的id
     */
    @Override
    public void deleteById(Long noteId){
        try{
            Note note = this.getById(noteId);
            note.setStatus(0);
            this.updateById(note);

            noteTagMapper.deleteNoteAndTagByNoteId(noteId);

        }catch (Exception e){
            throw new BusinessException("删除笔记失败");
        }
    }

    /**
     * 根据 userId 获取 note集合
     * @param userId    用户id
     * @return          noteVO集合
     */
    @Override
    public List<NoteVO> selectNoteByUserId(Long userId) {
        try{

            LambdaQueryWrapper<Note> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Note::getCreateBy, userId);
            queryWrapper.eq(Note::getStatus, 1);
            queryWrapper.orderByDesc(Note::getUpdateTime);
            List<Note> noteList = this.list(queryWrapper);

            return noteListTONoteVOList(noteList);
        }catch (Exception e){
            throw new BusinessException("获取note异常");
        }
    }

    /**
     * 添加笔记
     * @param noteDTO   笔记dto对象
     * @return          noteId
     */
    @Transactional
    @Override
    public Long addNote(NoteDTO noteDTO) {
        try{

            Note note = noteConverter.noteDTOToNote(noteDTO);
            noteMapper.insert(note);
            Long noteId = note.getNoteId();

            List<String> tags = noteDTO.getTags();

            // 提取公共逻辑
            Long userId = SecurityUtils.getUserId();
            LambdaQueryWrapper<NoteTag> baseWrapper = new LambdaQueryWrapper<>();
            baseWrapper.eq(NoteTag::getUserId, userId);


            for (String tag : tags) {

                LambdaQueryWrapper<NoteTag> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.setEntity(baseWrapper.getEntity());        // 复制公共逻辑
                queryWrapper.eq(NoteTag::getTagName, tag);
                NoteTag noteTag = noteTagMapper.selectOne(queryWrapper);

                // 判断tag是否需要新增
                if (StringUtils.isNull(noteTag)) {

                    noteTag = new NoteTag(userId, tag);
                    noteTagMapper.insert(noteTag);

                }

                // 建立多对多关系
                noteTagService.addNoteTag(noteId, noteTag.getTagId());
            }

            return noteId;
        }catch (Exception e){
            throw new BusinessException("添加笔记异常");
        }
    }

    /**
     * 修改笔记接口
     * @param noteDTO   笔记dto对象
     */
    @Transactional
    @Override
    public void updateNote(NoteDTO noteDTO) {
        try{

            Note note = noteConverter.noteDTOToNote(noteDTO);
            noteMapper.updateById(note);
            Long noteId = note.getNoteId();

            List<String> tagNames = noteTagMapper.selectTagsByNoteId(noteId);

            List<String> tags = noteDTO.getTags();

            LambdaQueryWrapper<NoteTag> baseWrapper = new LambdaQueryWrapper<>();
            Long userId = SecurityUtils.getUserId();
            baseWrapper.eq(NoteTag::getUserId, userId);

            for (String tag : tags) {
                LambdaQueryWrapper<NoteTag> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.setEntity(baseWrapper.getEntity());        // 复制公共逻辑
                queryWrapper.eq(NoteTag::getTagName, tag);
                NoteTag noteTag = noteTagMapper.selectOne(queryWrapper);

                // 判断tag是否需要新增
                if (StringUtils.isNull(noteTag)) {
                    noteTag = new NoteTag(userId, tag);
                    noteTagMapper.insert(noteTag);

                    // 建立多对多关系
                    noteTagService.addNoteTag(noteId, noteTag.getTagId());
                    tagNames.add(tag);
                }

                // 判断 note 是否存在 tag
                if (!tagNames.contains(tag))
                    // tag有数据，但note_tag没有数据
                    noteTagService.addNoteTag(noteId, noteTag.getTagId());

            }
        }catch (Exception e){
            throw new BusinessException("保存笔记异常");
        }
    }

    /**
     * 抽取封装方法：
     * 将 note 集合转化为 noteVO集合
     *
     * @param noteList  note集合
     * @return          noteVO集合
     */
    private List<NoteVO> noteListTONoteVOList(List<Note> noteList){
        try{
            List<NoteVO> noteVOList = noteConverter.noteListToNoteVOList(noteList);
            noteVOList = noteVOList.stream().peek(noteVO -> {

                Long noteId = noteVO.getNoteId();
                noteVO.setTags(noteTagMapper.selectTagsInNoteByNoteId(noteId));

            }).collect(Collectors.toList());

            return noteVOList;
        }catch (Exception e){
            throw new BusinessException("获取note集合异常");
        }
    }
}




